package com.tbit.main.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.tbit.main.constant.BrandRemoteConfigConstant;
import com.tbit.main.constant.RedisConstant;
import com.tbit.main.dao.core.AccountDao;
import com.tbit.main.dao.core.AccountUserDao;
import com.tbit.main.dao.core.BrandRemoteConfigDao;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.Account;
import com.tbit.main.pojo.AccountUserBound;
import com.tbit.main.pojo.BrandRemoteConfig;
import com.tbit.main.service.AccountUserFreeLoginService;
import com.tbit.main.service.RedisService;
import com.tbit.main.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @AUTHOR: wei.xing
 * @DATE: 2023-05-15 17:18
 **/
@Slf4j
@Service
public class AccountFreeLoginServiceImpl implements AccountUserFreeLoginService {

    @Autowired
    private AccountUserDao accountUserDao;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private BrandRemoteConfigDao brandRemoteConfigDao;
    @Autowired
    private AccountDao accountDao;

    @Override
    public void freeLogin(Integer accountUserId, Integer accountId) {

        //是否刷新token
        if (isRefreshToken(accountId)) {
            BrandRemoteConfig brandRemoteConfig = getBrandRemoteConfig(accountUserId);
            if (brandRemoteConfig != null) {

                Date tokenExpireDate = getTokenExpireDate(accountUserId, brandRemoteConfig);
                int seconds = (int) DateUtil.between(new Date(), tokenExpireDate, DateUnit.SECOND, false);
                if (seconds <= 0) {
                    tokenService.destroyToken();
                    throw new BaseException("请先登录");
                }
                //token续期
                tokenService.refreshToken(seconds);
                refreshLoginDate(accountUserId, seconds, getLastLoginDate(accountUserId));
            }
        }
    }

    @Override
    public void refreshLoginDate(Integer accountUserId, Integer second, Date date) {
        String loginDateKey = RedisConstant.ACCOUNT_USER_MAIN_LOGIN_DATE + accountUserId;
        redisService.add(loginDateKey, JSON.toJSONString(date), second);
    }

    private Date getTokenExpireDate(Integer accountUserId, BrandRemoteConfig brandRemoteConfig) {
        String[] strings = brandRemoteConfig.getParamKV().split("&");
        String freeLoginMode = strings[0].substring(strings[0].indexOf("=") + 1);
        int effectiveMinute = Integer.parseInt(strings[1].substring(strings[1].indexOf("=") + 1));

        Date tokenExpireDate;
        if ("0".equals(freeLoginMode)) {
            //根据最近请求时间
            tokenExpireDate = DateUtil.offsetMinute(new Date(), effectiveMinute);
        } else {
            //根据最近登录时间
            Date lastLoginDate = getLastLoginDate(accountUserId);
            if (lastLoginDate == null) {
                throw new BaseException("请先登录");
            }
            tokenExpireDate = DateUtil.offsetMinute(lastLoginDate, effectiveMinute);
        }
        return tokenExpireDate;
    }


    private BrandRemoteConfig getBrandRemoteConfig(Integer accountUserId) {
        AccountUserBound accountUserBound = accountUserDao.getBoundByUserId(accountUserId);
        Integer brandId = accountUserBound.getAccountId();
        Account account = accountDao.getByAccountId(brandId);
        if (account.getType().equals(2)) {
            brandId = account.getParentId();
        } else if (account.getType().equals(3)) {
            brandId = accountDao.getByAccountId(account.getParentId()).getParentId();
        }
        return brandRemoteConfigDao.getBrandRemoteConfig(brandId, BrandRemoteConfigConstant.MAIN_FREE_LOGIN);
    }

    private boolean isRefreshToken(Integer accountId) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getParameter("token");
        String freeLoginKey = RedisConstant.ACCOUNT_USER_MAIN_FREE_LOGIN + accountId + ":" + token;
        if (!redisService.hasKey(freeLoginKey)) {
            redisService.add(freeLoginKey, "", 3600);
            return true;
        }
        return false;
    }


    private Date getLastLoginDate(Integer accountUserId) {
        String loginDateKey = RedisConstant.ACCOUNT_USER_MAIN_LOGIN_DATE + accountUserId;
        String str = redisService.get(loginDateKey);
        if (str == null) {
            return null;
        }
        return JSON.parseObject(str, Date.class);
    }
}
